#!/usr/bin/env python3
import os
import shutil
import sys
import datetime
from pathlib import Path
import argparse


def count_files(directory: Path, extensions: list) -> dict:
    """统计目录的直接子目录中指定扩展名的文件数量
    
    Args:
        directory: 要扫描的目录路径
        extensions: 要统计的文件扩展名列表（不带点）
        
    Returns:
        包含各扩展名文件数量的字典
    """
    
    count = {ext: 0 for ext in extensions}
    for ext in extensions:
        count[ext] = len(list(directory.glob(f"*/*{ext}")))
    return count


def find_subdirs_without_spec(directory: Path) -> list:
    """查找指定目录下没有.spec文件的直接子目录
    
    Args:
        directory: 要检查的父目录路径
        
    Returns:
        不包含.spec文件的直接子目录路径列表
    """
    subdirs_without_spec = []
    # 获取所有直接子目录
    for subdir in directory.iterdir():
        if subdir.is_dir():
            # 检查子目录中是否存在.spec文件
            spec_files = list(subdir.glob("*.spec"))
            if not spec_files:
                subdirs_without_spec.append(subdir)
    return subdirs_without_spec

def find_specs_not_in_direct_subdirs(directory: Path) -> list:
    """查找不在直接子目录中的.spec文件
    
    Args:
        directory: 要检查的根目录路径
        
    Returns:
        不在直接子目录中的.spec文件路径列表
    """
    # 获取所有直接子目录
    direct_subdirs = {subdir for subdir in directory.iterdir() if subdir.is_dir()}
    
    # 查找所有.spec文件
    all_specs = list(directory.rglob("*.spec"))
    
    # 筛选不在直接子目录中的.spec文件
    specs_not_in_direct = []
    for spec in all_specs:
        # 获取文件所在的直接父目录
        parent_dir = spec.parent
        # 检查父目录是否是根目录的直接子目录
        if parent_dir not in direct_subdirs:
            specs_not_in_direct.append(spec)
    
    return specs_not_in_direct


def find_duplicate_patch_names(patch_files: list) -> dict:
    """查找patch_files中文件名相同的文件
    
    Args:
        patch_files: 包含.patch文件路径的列表
        
    Returns:
        键为文件名，值为包含该文件名的所有路径列表的字典
    """
    name_map = {}
    for file in patch_files:
        filename = file.name
        if filename in name_map:
            name_map[filename].append(file)
        else:
            name_map[filename] = [file]
    # 筛选出有重复的文件名
    duplicates = {name: paths for name, paths in name_map.items() if len(paths) > 1}
    return duplicates


def count_files_rglob(directory: Path, extensions: list) -> dict:
    """统计目录中指定扩展名的文件数量
    
    Args:
        directory: 要扫描的目录路径
        extensions: 要统计的文件扩展名列表（不带点）
        
    Returns:
        包含各扩展名文件数量的字典
    """
    
    count = {ext: 0 for ext in extensions}
    for ext in extensions:
        count[ext] = len(list(directory.rglob(f"*{ext}")))
    return count

def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('--source-dir', default=os.path.join(os.getcwd(), "downloads"), help='agiros下载目录路径 (默认: ./downloads)')
    parser.add_argument('--rpm-sources', default=os.path.join(os.getcwd(), "build/SOURCES"), help='编译sources目录 (默认: ./build/SOURCES)')
    parser.add_argument('--rpm-specs', default=os.path.join(os.getcwd(), "build/SPECS"), help='编译specs目录 (默认: ./build/SPECS)')
    parser.add_argument('--rpm-specs-all', default=os.path.join(os.getcwd(), "build/SPECS_ALL"), help='编译specs目录 (默认: ./build/SPECS_ALL)')

    args = parser.parse_args()

    source_dir = Path(args.source_dir).resolve()
    rpm_sources = Path(args.rpm_sources).resolve()
    rpm_specs = Path(args.rpm_specs).resolve()
    rpm_specs_all = Path(args.rpm_specs_all).resolve()

    # 确保目录存在
    source_dir.mkdir(parents=True, exist_ok=True)
    rpm_sources.mkdir(parents=True, exist_ok=True)
    rpm_specs.mkdir(parents=True, exist_ok=True)
    rpm_specs_all.mkdir(parents=True, exist_ok=True)

    # 显示源目录初始文件统计
    print(f"源目录初始文件统计 glob ({source_dir}):")
    source_counts = count_files(source_dir, [".tar.gz", ".patch", ".spec"])
    print(f"- .tar.gz 文件: {source_counts['.tar.gz']}")
    print(f"- .patch  文件: {source_counts['.patch']}")
    print(f"- .spec   文件: {source_counts['.spec']}")
    print()

    print(f"源目录初始文件统计 rglob ({source_dir}):")
    source_counts = count_files_rglob(source_dir, [".tar.gz", ".patch", ".spec"])
    print(f"- .tar.gz 文件: {source_counts['.tar.gz']}")
    print(f"- .patch  文件: {source_counts['.patch']}")
    print(f"- .spec   文件: {source_counts['.spec']}")
    print()

    # 扫描要复制的文件
    print("扫描将要复制的文件...")
    print()

    # 查找所有.spec文件
    spec_files = list(source_dir.glob("*/*.spec"))
    spec_count = len(spec_files)

    # 查找同级.patch文件
    patch_files = set()
    for spec_file in spec_files:
        dir_path = spec_file.parent
        for patch in dir_path.glob("*.patch"):
            patch_files.add(patch)
    patch_files = sorted(patch_files)
    patch_count = len(patch_files)

    # 查找同级.tar.gz文件
    tar_files = set()
    for spec_file in spec_files:
        dir_path = spec_file.parent
        for tar in dir_path.glob("*.tar.gz"):
            tar_files.add(tar)
    tar_files = sorted(tar_files)
    tar_count = len(tar_files)

    # 显示扫描结果
    print("\n扫描完成：")
    print(f"- 找到 {spec_count} 个.spec文件")
    print(f"- 找到 {tar_count} 个同级.tar.gz文件")
    print(f"- 找到 {patch_count} 个同级.patch文件")
    print()

    # 检查缺少.spec文件的子目录
    print("检查缺少.spec文件的子目录...")
    subdirs_without_spec = find_subdirs_without_spec(source_dir)
    if subdirs_without_spec:
        print("\n=== 以下子目录中未找到.spec文件 ===")
        for subdir in subdirs_without_spec:
            print(subdir)
    else:
        print("\n所有直接子目录都包含.spec文件。")
    print()

    # 检查不在直接子目录中的.spec文件
    print("检查不在直接子目录中的.spec文件...")
    specs_not_in_direct = find_specs_not_in_direct_subdirs(source_dir)
    if specs_not_in_direct:
        print("\n=== 以下.spec文件不在直接子目录中 ===")
        for spec in specs_not_in_direct:
            print(spec)
    else:
        print("\n所有.spec文件都位于直接子目录中。")
    print()

    # 检查重复的.patch文件名
    print("检查重复的.patch文件名...")
    duplicate_patches = find_duplicate_patch_names(patch_files)
    if duplicate_patches:
        print("\n=== 发现以下重复的.patch文件名 ===")
        for name, paths in duplicate_patches.items():
            print(f"文件名: {name}")
            for path in paths:
                print(f"  {path}")
    else:
        print("\n未发现重复的.patch文件名。")
    print()

if __name__ == "__main__":
    main()